<template>
  <div class="ai-chat">
    <!-- 顶部栏 -->
    <div class="chat-header">
      <div class="header-left">
        <el-button @click="goBack" icon="ArrowLeft" circle />
        <h2 class="app-name">{{ appInfo.appName || '应用对话' }}</h2>
        <el-tag type="primary">
          <dict-tag :options="generation_type" :value="appInfo.codeGenType" size="small" />
        </el-tag>
      </div>
      <div class="header-right">
        <el-button 
          type="info" 
          @click="showAppDetail" 
          icon="InfoFilled"
          style="margin-right: 10px;"
        >
          应用详细
        </el-button>
        <el-button 
          v-if="canDownloadCode"
          type="success" 
          @click="downloadCode" 
          :loading="downloading"
          icon="Download"
          style="margin-right: 10px;"
        >
          下载代码
        </el-button>
        <el-button 
          v-else
          type="info" 
          disabled
          icon="Clock"
          style="margin-right: 10px;"
          title="应用正在生成中，请稍等"
        >
          应用生成中...
        </el-button>
        <el-button 
          type="primary" 
          @click="deployApp" 
          :loading="deploying"
          icon="Upload"
        >
          部署应用
        </el-button>
      </div>
    </div>

    <!-- 主要内容区域 -->
    <div class="chat-content">
      <!-- 左侧对话区域 -->
      <div class="chat-panel">
        <!-- 消息区域 -->
        <div class="messages-container" ref="messagesContainer">
          <div 
            v-for="message in messages" 
            :key="message.id" 
            :class="['message', message.role]"
          >
            <div class="message-avatar">
              <el-avatar 
                v-if="message.role === 'user'" 
                :size="36" 
                :src="userAvatar" 
                icon="User"
              />
              <div v-else-if="message.role === 'tool_execution_result'" class="tool-avatar">
                🔧
              </div>
              <div v-else class="ai-avatar">
                🤖
              </div>
            </div>
            <div class="message-content">
              <div class="message-bubble">
                <!-- AI消息特殊显示：包含思考内容和回复内容 -->
                <div v-if="message.role === 'assistant'" class="ai-message-container">
                  <!-- 思考内容区域 -->
                  <div v-if="message.thinking" class="thinking-section">
                    <div class="thinking-header" @click="toggleThinkingExpanded(message.id)">
                      <span class="thinking-icon">💭</span>
                      <span class="thinking-title">思考过程</span>
                      <span class="thinking-toggle">
                        <i :class="isThinkingExpanded(message.id) ? 'el-icon-arrow-up' : 'el-icon-arrow-down'"></i>
                      </span>
                    </div>
                    <div 
                      class="thinking-content" 
                      :class="{ 'thinking-collapsed': !isThinkingExpanded(message.id) }"
                    >
                      {{ message.thinking }}
                    </div>
                  </div>
                  
                  <!-- AI回复内容区域 -->
                  <div class="ai-response-section">
                    <div v-if="message.streaming" class="streaming-content">
                      <div v-html="formatMessageWithHighlight(message.content)"></div>
                      <div class="typing-indicator">
                        <span></span>
                        <span></span>
                        <span></span>
                      </div>
                    </div>
                    <div v-else v-html="formatMessageWithHighlight(message.content)"></div>
                  </div>
                </div>
                
                <!-- 其他类型消息的原有显示逻辑 -->
                <div v-else>
                  <div v-if="message.streaming" class="streaming-content">
                    <div v-html="formatMessageWithHighlight(message.content)"></div>
                    <div class="typing-indicator">
                      <span></span>
                      <span></span>
                      <span></span>
                    </div>
                  </div>
                  <div v-else v-html="formatMessageWithHighlight(message.content)"></div>
                </div>
              </div>
              <div class="message-time">
                {{ formatTime(message.timestamp) }}
              </div>
            </div>
          </div>
        </div>

        <!-- 选中元素信息显示区域 -->
        <div v-if="selectedElements.length > 0" class="selected-elements-area">
          <el-alert
            v-for="(element, index) in selectedElements"
            :key="element.uniqueId"
            :title="`已选中元素: ${element.tagName}${element.id ? '#' + element.id : ''}`"
            :description="element.textContent ? element.textContent.substring(0, 50) + (element.textContent.length > 50 ? '...' : '') : '无文本内容'"
            type="info"
            :closable="true"
            @close="removeSelectedElement(element.uniqueId)"
            show-icon
            class="element-alert"
          >
            <template #default>
              <div class="element-info">
                <div class="element-basic">
                  <span class="tag-name">{{ element.tagName }}</span>
                  <span v-if="element.id" class="element-id">#{{ element.id }}</span>
                  <span v-if="element.className" class="element-class">.{{ element.className.split(' ')[0] }}</span>
                </div>
                <div v-if="element.textContent" class="element-text">
                  {{ element.textContent.substring(0, 100) }}{{ element.textContent.length > 100 ? '...' : '' }}
                </div>
                <div class="element-selector">
                  <span class="selector-label">选择器:</span>
                  <code class="selector-code">{{ element.selector }}</code>
                </div>
                <div class="element-selector">
                  <span class="selector-label">页面路径:</span>
                  <code class="selector-code">{{ element.pagePath }}</code>
                </div>
              </div>
            </template>
          </el-alert>
        </div>

        <!-- 输入框区域 -->
        <div class="input-area">
          <div class="input-container">
            <div class="input-wrapper">
              <el-input
                v-model="currentMessage"
                type="textarea"
                :rows="3"
                placeholder="描述你想要的功能或改进..."
                class="message-input"
                :disabled="isActivelyStreaming"
                @keydown.enter.exact="sendMessage"
                @keydown.enter.shift.exact.prevent="currentMessage += '\n'"
              />
              <div class="send-button-wrapper">
                <el-button 
                  v-if="!isStreaming"
                  type="primary" 
                  @click="sendMessage" 
                  :disabled="!currentMessage.trim()"
                  class="send-btn"
                  icon="Promotion"
                  circle
                >
                </el-button>
                <el-button 
                  v-else-if="isPaused"
                  type="warning" 
                  @click="resumeStreaming"
                  class="send-btn"
                  icon="VideoPlay"
                  circle
                >
                </el-button>
                <el-button 
                  v-else
                  type="danger" 
                  @click="pauseStreaming"
                  class="send-btn"
                  icon="VideoPause"
                  circle
                >
                </el-button>
              </div>
            </div>
          </div>
          <div class="input-tip">
            按 Enter 发送，Shift + Enter 换行
          </div>
        </div>
      </div>

      <!-- 右侧网页展示区域 -->
      <div class="preview-panel">
        <div class="preview-header">
          <h3>生成效果预览</h3>
          <div class="preview-actions">
            <el-button 
              v-if="previewUrl && !isStreaming"
              :type="isEditMode ? 'success' : 'default'"
              @click="toggleEditMode"
              class="edit-btn"
              :icon="isEditMode ? 'Check' : 'Edit'"
              :title="isEditMode ? '退出编辑模式' : '进入编辑模式'"
            >
              {{ isEditMode ? '退出编辑' : '编辑模式' }}
            </el-button>
            <el-button 
              v-if="previewUrl" 
              @click="openInNewTab" 
              icon="View"
              type="primary"
              text
            >
              新窗口打开
            </el-button>
            <el-button @click="refreshPreview" icon="Refresh" text>
              刷新
            </el-button>
          </div>
        </div>
        <div class="preview-content">
          <div v-if="!previewUrl && !isStreaming" class="preview-placeholder">
            <el-icon size="80"><Document /></el-icon>
            <p>开始对话后，生成的网站将在这里显示</p>
          </div>
          <div v-else-if="isStreaming" class="preview-loading">
            <el-icon class="is-loading" size="40"><Loading /></el-icon>
            <p v-if="!isPaused">AI 正在生成中，请稍候...</p>
            <p v-else>AI 输出已暂停</p>
          </div>
          <div v-else-if="buildStatus.status === 'pending'" class="preview-building">
            <el-icon class="is-loading" size="40"><Loading /></el-icon>
            <p>{{ buildStatus.message }}</p>
            <p class="build-status-text">正在构建项目，请稍候...</p>
          </div>
          <div v-else-if="buildStatus.status === 'not_found'" class="preview-building">
            <el-icon size="40"><Document /></el-icon>
            <p>{{ buildStatus.message }}</p>
            <p class="build-status-text">等待项目生成...</p>
          </div>
          <iframe 
            v-else
            :src="previewUrl" 
            class="preview-iframe"
            @load="onIframeLoad"
          ></iframe>
        </div>
      </div>
    </div>

    <!-- 应用详细信息右弹窗 -->
    <el-drawer
      v-model="appDetailVisible"
      title="应用详细信息"
      direction="rtl"
      size="500px"
    >
      <div class="app-detail-content">
        <div v-if="Object.keys(appDetailInfo).length > 0">
          <el-descriptions :column="1" border>
            <el-descriptions-item label="应用ID">
              <el-tag type="info">{{ appDetailInfo.id || '未知' }}</el-tag>
            </el-descriptions-item>
            <el-descriptions-item label="应用名称">
              {{ appDetailInfo.appName || '未设置' }}
            </el-descriptions-item>
            <el-descriptions-item label="应用封面" v-if="appDetailInfo.cover">
              <img 
                :src="appDetailInfo.cover" 
                alt="应用封面" 
                class="app-cover-image" 
                @click="showImagePreview(appDetailInfo.cover)"
              />
            </el-descriptions-item>
            <el-descriptions-item label="代码生成类型">
              <el-tag type="primary">
                <dict-tag :options="generation_type" :value="appDetailInfo.codeGenType" size="small" />
              </el-tag>
            </el-descriptions-item>
            <el-descriptions-item label="部署标识" v-if="appDetailInfo.deployKey">
              <el-tag type="success">{{ appDetailInfo.deployKey }}</el-tag>
            </el-descriptions-item>
            <el-descriptions-item label="部署时间" v-if="appDetailInfo.deployedTime">
              {{ formatDateTime(appDetailInfo.deployedTime) }}
            </el-descriptions-item>
            <el-descriptions-item label="应用状态">
              <el-tag :type="appDetailInfo.priority === 99 ? 'success' : 'info'" size="large">
                <el-icon v-if="appDetailInfo.priority === 99"><Star /></el-icon>
                {{ appDetailInfo.priority === 99 ? '精选' : '普通' }}
              </el-tag>
            </el-descriptions-item>
            <el-descriptions-item label="初始提示词">
              <div class="init-prompt">{{ appDetailInfo.initPrompt || '暂无' }}</div>
            </el-descriptions-item>
            <el-descriptions-item label="创建时间">
              {{ formatDateTime(appDetailInfo.createTime) }}
            </el-descriptions-item>
            <el-descriptions-item label="更新时间">
              {{ formatDateTime(appDetailInfo.updateTime) }}
            </el-descriptions-item>
          </el-descriptions>
          
          <!-- 创建者信息 -->
          <div class="creator-info" v-if="appDetailInfo.user">
            <h4>创建者信息</h4>
            <el-descriptions :column="1" border>
              <el-descriptions-item label="用户ID">
                <el-tag type="info">{{ appDetailInfo.user.userId || '未知' }}</el-tag>
              </el-descriptions-item>
              <el-descriptions-item label="用户账号">
                {{ appDetailInfo.user.userName || '未知' }}
              </el-descriptions-item>
              <el-descriptions-item label="用户昵称">
                {{ appDetailInfo.user.nickName || '未设置' }}
              </el-descriptions-item>
              <el-descriptions-item label="用户头像" v-if="appDetailInfo.user.avatar">
                <img :src="appDetailInfo.user.avatar" alt="用户头像" class="user-avatar-image" />
              </el-descriptions-item>
              <el-descriptions-item label="用户简介" v-if="appDetailInfo.user.remark">
                {{ appDetailInfo.user.remark }}
              </el-descriptions-item>
              <el-descriptions-item label="创建时间">
                {{ formatDateTime(appDetailInfo.user.createTime) }}
              </el-descriptions-item>
            </el-descriptions>
          </div>
          
          <div class="detail-actions" style="margin-top: 20px;">
            <el-button type="primary" @click="editApp">
              <el-icon><Edit /></el-icon>
              编辑应用
            </el-button>
          </div>
        </div>
        
        <div v-else class="loading-content" style="text-align: center; padding: 40px;">
          <el-icon class="is-loading"><Loading /></el-icon>
          <p>加载中...</p>
        </div>
      </div>
    </el-drawer>

    <!-- 图片预览弹窗 -->
    <el-dialog
      v-model="imagePreviewVisible"
      width="1000px"
      center
      :before-close="closeImagePreview"
    >
      <div class="image-preview-container">
        <img 
          :src="previewImageUrl" 
          alt="应用封面预览" 
          class="preview-image"
        />
      </div>
    </el-dialog>
  </div>
</template>

<script setup name="AiChat">
import { ref, reactive, onMounted, nextTick, getCurrentInstance, onUnmounted, computed } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { ArrowLeft, Upload, Download, InfoFilled, Edit, Star, User, Promotion, Document, View, Refresh, Loading, DocumentCopy, VideoPause, VideoPlay, Check } from '@element-plus/icons-vue'
import { getAppDetail, deployApp as deployAppApi, getChatMessages, downloadAppCode, getBuildStatus } from '@/api/ai/app'
import { parseTime } from '@/utils/ruoyi'
import { getToken } from '@/utils/auth'
import hljs from 'highlight.js'
import 'highlight.js/styles/github.css'
import { VisualEditor } from '@/utils/visualEditor'

const { proxy } = getCurrentInstance()
const { generation_type } = proxy.useDict('generation_type')
const route = useRoute()
const router = useRouter()

// 响应式数据
const appInfo = ref({})
const messages = ref([])
const currentMessage = ref('')
const isStreaming = ref(false)
const isPaused = ref(false)
const deploying = ref(false)
const downloading = ref(false)
const previewUrl = ref('')
const userAvatar = ref('')
const appDetailVisible = ref(false)
const appDetailInfo = ref({})
const imagePreviewVisible = ref(false)
const previewImageUrl = ref('')
const messagesContainer = ref(null)

// 可视化编辑相关状态
const isEditMode = ref(false)
const selectedElements = ref([])
const visualEditor = ref(null)

// thinking展开/收缩状态管理
const thinkingExpandedStates = ref({}) // 存储每个消息的thinking展开状态

// 构建状态相关
const buildStatus = ref({
  status: 'not_found', // not_found, pending, completed
  message: '',
  isBuilding: false,
  projectExists: false,
  distExists: false,
  buildTime: null
})
const pollingInterval = ref(null)
const isPolling = ref(false)

// 计算属性：判断是否可以下载代码
const canDownloadCode = computed(() => {
  // 如果有预览URL且应用有ID和代码生成类型，说明应用已生成完成
  return previewUrl.value && appInfo.value.id && appInfo.value.codeGenType && !isStreaming.value
})

// 计算属性：判断是否正在流式输出（包括暂停状态）
const isActivelyStreaming = computed(() => {
  return isStreaming.value && !isPaused.value
})

// SSE 连接
let eventSource = null
let messageId = 0
let streamReader = null
let currentAiMessage = null

// 获取应用详情
const loadAppInfo = async () => {
  try {
    const response = await getAppDetail(route.params.appId)
    if (response.code === 200) {
      appInfo.value = response.data
      
      // 检查是否是新创建的应用
      const isNewApp = route.query.new === 'true'
      
      if (isNewApp) {
        // 新创建的应用，发送初始消息
        setTimeout(() => {
          sendInitialMessage()
        }, 1000)
      } else {
        // 已有应用，加载历史聊天记录
        await loadChatHistory()
      }
      
      // 加载预览效果
      updatePreview()
      
      // 根据代码生成类型决定预览方式
      if(appInfo.value.codeGenType === 'vue_project'){
        // vue_project 需要构建，开始轮询构建状态
        startPolling()
      } else {
        // html 和 multi_file 不需要构建，直接在 iframe 中进行页面预览
        buildStatus.value.status = 'completed'
        buildStatus.value.message = '预览就绪'
      }

    }
  } catch (error) {
    proxy.$modal.msgError('获取应用详情失败')
  }
}

// 发送初始消息
const sendInitialMessage = () => {
  if (appInfo.value.initPrompt && messages.value.length === 0) {
    currentMessage.value = appInfo.value.initPrompt
    sendMessage()
  }
}

// 加载历史聊天记录
const loadChatHistory = async () => {
  try {
    const response = await getChatMessages(route.params.appId)
    if (response.code === 200 && response.data && response.data.length > 0) {
      // 将后端返回的消息格式转换为前端格式
      const historyMessages = response.data.map((msg, index) => {
        if (msg.messageType === 'USER') {
          return {
            id: ++messageId,
            role: 'user',
            content: msg.text || '',
            timestamp: new Date() // 如果后端有时间戳，可以使用实际时间
          }
        } else if (msg.messageType === 'AI') {
          return {
            id: ++messageId,
            role: 'assistant',
            content: msg.text || '',
            thinking: msg.thinking || '', // 添加思考内容字段
            timestamp: new Date(), // 如果后端有时间戳，可以使用实际时间
            streaming: false
          }
        }else if (msg.messageType === 'TOOL_EXECUTION_RESULT') {
          return {
            id: ++messageId,
            role: 'tool_execution_result',
            content: msg.text || '',
            timestamp: new Date(), // 如果后端有时间戳，可以使用实际时间
            streaming: false
          }
        }
      }).filter(Boolean) // 过滤掉undefined的消息
      
      messages.value = historyMessages
      
      // 滚动到底部显示最新消息
      nextTick(() => {
        scrollToBottom()
      })
    }
  } catch (error) {
    // 不显示错误提示，因为可能是新应用没有历史记录
  }
}

// 发送消息
const sendMessage = () => {
  if (!currentMessage.value.trim() || isStreaming.value) {
    return
  }

  // 构建包含选中元素信息的消息内容
  let messageContent = ''
  
  if (selectedElements.value.length > 0) {
    // 第一行添加修改指令
    messageContent += '请对以下元素进行修改，并且只修改这部分\n\n'
    
    // 添加选中的页面元素信息
    messageContent += '【选中的页面元素信息】\n'
    selectedElements.value.forEach((element, index) => {
      messageContent += `${index + 1}. 元素类型: ${element.tagName}\n`
      if (element.id) {
        messageContent += `   ID: ${element.id}\n`
      }
      if (element.className) {
        messageContent += `   类名: ${element.className}\n`
      }
      if (element.textContent) {
        messageContent += `   文本内容: ${element.textContent.substring(0, 200)}${element.textContent.length > 200 ? '...' : ''}\n`
      }
      messageContent += `   CSS选择器: ${element.selector}\n`
      if (element.pagePath) {
        messageContent += `   页面路径: ${element.pagePath}\n`
      }
      messageContent += `   位置信息: top:${element.rect.top}, left:${element.rect.left}, width:${element.rect.width}, height:${element.rect.height}\n`
    })
    
    // 最后添加用户的输入信息
    messageContent += '\n用户需求: \n' + currentMessage.value
  } else {
    // 没有选中元素时，直接使用用户输入
    messageContent = currentMessage.value
  }

  const userMessage = {
    id: ++messageId,
    role: 'user',
    content: messageContent,
    timestamp: new Date()
  }
  
  messages.value.push(userMessage)
  
  // 创建 AI 回复消息
  const aiMessage = reactive({
    id: ++messageId,
    role: 'assistant',
    content: '',
    thinking: '', // 添加思考内容字段
    timestamp: new Date(),
    streaming: true
  })
  messages.value.push(aiMessage)

  // 保存当前AI消息引用
  currentAiMessage = aiMessage
  
  // 开始流式对话
  startStreaming(messageContent, aiMessage)
  currentMessage.value = ''
  
  // 发送消息后清除选中元素并退出编辑模式
  selectedElements.value = []
  if (isEditMode.value) {
    toggleEditMode()
  }
  
  nextTick(() => {
    scrollToBottom()
  })
}

// 开始流式对话
const startStreaming = async (message, aiMessage) => {
  isStreaming.value = true
  let streamCompleted = false
  
  try {
    // 构建URL参数
    const params = new URLSearchParams({
      appId: route.params.appId || '',
      message: message,
      agent: "false"
    })
    
    // 直接使用后端接口地址
    const url = `/stream-api/ai/app/chat/gen/code?${params}`
    
    // 使用 fetch 进行流式请求
    const response = await fetch(url, {
      method: 'GET',
      headers: {
        'Accept': 'text/event-stream',
        'Cache-Control': 'no-cache',
        'Authorization': `Bearer ${getToken()}` // 添加认证头
      },
    })
    
    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`)
    }
    
    const reader = response.body.getReader()
    streamReader = reader // 保存流读取器引用
    const decoder = new TextDecoder()
    let fullContent = ''
    
    const readStream = async () => {
      try {
        while (true) {
          // 检查是否被暂停
          if (isPaused.value) {
            // 如果被暂停，等待恢复
            await new Promise(resolve => {
              const checkResume = () => {
                if (!isPaused.value) {
                  resolve()
                } else {
                  setTimeout(checkResume, 100)
                }
              }
              checkResume()
            })
          }
          
          const { done, value } = await reader.read()
          
          if (done || streamCompleted) {
            isStreaming.value = false
            isPaused.value = false
            aiMessage.streaming = false
            streamReader = null
            currentAiMessage = null
            updatePreview()
            break
          }
          
          const chunk = decoder.decode(value, { stream: true })
          const lines = chunk.split('\n')
          
          for (const line of lines) {
            if (line.trim() === '') continue
            // 处理 SSE 格式的数据
            if (line.startsWith('data:')) {
              const data = line.slice(5).trim()
              if (data) {
                try {
                  // 解析JSON包装的数据
                  const parsed = JSON.parse(data)
                  const content = parsed.d
            
                  
                  // 拼接内容
                  if (content !== undefined && content !== null) {
                    fullContent += content
                    aiMessage.content = fullContent
                    aiMessage.streaming = true
                    nextTick(() => {
                      scrollToBottom()
                    })
                  }
                } catch (error) {
                  // 解析SSE数据失败，忽略错误继续处理
                }
              }
            }
            // 处理事件类型
            else if (line.startsWith('event: ')) {
              const eventType = line.slice(7).trim()
              if (eventType === 'done') {
                streamCompleted = true
                isStreaming.value = false
                aiMessage.streaming = false
                updatePreview()
                return
              }
            }
          }
        }
      } catch (error) {
        handleStreamError(error, aiMessage)
      }
    }
    
    readStream()
    
  } catch (error) {
    handleStreamError(error, aiMessage)
  }
}

// 错误处理函数
const handleStreamError = (error, aiMessage) => {
  aiMessage.content = '抱歉，生成过程中出现了错误，请重试。'
  aiMessage.streaming = false
  isStreaming.value = false
  isPaused.value = false
  streamReader = null
  currentAiMessage = null
  proxy.$modal.msgError('生成失败，请重试')
}

// 暂停流式输出
const pauseStreaming = () => {
  if (isStreaming.value && !isPaused.value) {
    isPaused.value = true
    proxy.$modal.msgSuccess('已暂停输出')
  }
}

// 恢复流式输出
const resumeStreaming = () => {
  if (isStreaming.value && isPaused.value) {
    isPaused.value = false
    proxy.$modal.msgSuccess('已恢复输出')
  }
}

// 更新预览
const updatePreview = () => {
  // 根据应用类型和ID构建预览URL
  if(appInfo.value.codeGenType && appInfo.value.id && appInfo.value.codeGenType === 'vue_project'){
    previewUrl.value = `/preview-api/static/${appInfo.value.codeGenType}_${appInfo.value.id}/dist/index.html`
  }else{
    previewUrl.value = `/preview-api/static/${appInfo.value.codeGenType}_${appInfo.value.id}/`
  }
  
  // 重置可视化编辑器状态
  if (visualEditor.value) {
    visualEditor.value.disableEditMode()
    visualEditor.value = null
  }
  isEditMode.value = false
  selectedElements.value = []
}

// 查询构建状态
const checkBuildStatus = async () => {
  if (!appInfo.value.id) return
  
  try {
    const response = await getBuildStatus(appInfo.value.id)
    if (response.code === 200) {
      buildStatus.value = response.data
      
      // 根据构建状态决定是否显示预览
      if (buildStatus.value.status === 'completed') {
        updatePreview()
        stopPolling()
      }
    }
  } catch (error) {
    console.error('查询构建状态失败:', error)
  }
}

// 开始轮询
const startPolling = () => {
  if (isPolling.value || !appInfo.value.id) return
  
  isPolling.value = true
  // 立即执行一次
  checkBuildStatus()
  
  // 每10秒轮询一次
  pollingInterval.value = setInterval(() => {
    checkBuildStatus()
  }, 10000)
}

// 停止轮询
const stopPolling = () => {
  if (pollingInterval.value) {
    clearInterval(pollingInterval.value)
    pollingInterval.value = null
  }
  isPolling.value = false
}

// 部署应用
const deployApp = async () => {
  deploying.value = true
  try {
    const response = await deployAppApi({ appId: parseInt(route.params.appId) })
    if (response.code === 200) {
      proxy.$modal.msgSuccess('部署成功！')
      // 如果有部署URL，显示自定义对话框
      if (response.data) {
        showDeploySuccessDialog(response.data)
      }
    }
  } catch (error) {
    proxy.$modal.msgError('部署失败')
  } finally {
    deploying.value = false
  }
}

// 下载应用代码
const downloadCode = async () => {
  // 检查是否可以下载
  if (!canDownloadCode.value) {
    proxy.$modal.msgWarning('应用正在生成中，请稍等...')
    return
  }
  
  downloading.value = true
  try {
    const appId = route.params.appId
    const response = await downloadAppCode(appId)
    
    // 创建下载链接
    const blob = new Blob([response], { type: 'application/zip' })
    const url = window.URL.createObjectURL(blob)
    const link = document.createElement('a')
    link.href = url
    
    // 设置下载文件名
    const fileName = `${appInfo.value.appName || 'app'}_${appId}.zip`
    link.download = fileName
    
    // 触发下载
    document.body.appendChild(link)
    link.click()
    document.body.removeChild(link)
    
    // 清理URL对象
    window.URL.revokeObjectURL(url)
    
    proxy.$modal.msgSuccess('代码下载成功！')
  } catch (error) {
    proxy.$modal.msgError('下载失败，请重试')
  } finally {
    downloading.value = false
  }
}

// 显示应用详细信息
const showAppDetail = async () => {
  try {
    const appId = route.params.appId
    const response = await getAppDetail(appId)
    if (response.code === 200) {
      appDetailInfo.value = response.data
      appDetailVisible.value = true
    }
  } catch (error) {
    proxy.$modal.msgError('获取应用详情失败')
  }
}

// 编辑应用
const editApp = () => {
  const appId = route.params.appId
  router.push(`/ai/app/edit/${appId}`)
}

// 显示图片预览
const showImagePreview = (imageUrl) => {
  previewImageUrl.value = imageUrl
  imagePreviewVisible.value = true
}

// 关闭图片预览
const closeImagePreview = () => {
  imagePreviewVisible.value = false
  previewImageUrl.value = ''
}

// 切换thinking展开/收缩状态
const toggleThinkingExpanded = (messageId) => {
  thinkingExpandedStates.value[messageId] = !thinkingExpandedStates.value[messageId]
}

// 检查thinking是否展开
const isThinkingExpanded = (messageId) => {
  return thinkingExpandedStates.value[messageId] || false
}

// 显示部署成功对话框
const showDeploySuccessDialog = (deployUrl) => {
  proxy.$msgbox({
    title: '部署成功',
    dangerouslyUseHTMLString: true,
    message: `
      <div class="deploy-success-content">
        <p style="margin-bottom: 15px; color: #67c23a; font-weight: 600;">🎉 应用已成功部署！</p>
        <p style="margin-bottom: 10px; color: #606266;">访问地址：</p>
        <div style="display: flex; align-items: center; gap: 10px; padding: 10px; background: #f5f7fa; border-radius: 6px; margin-bottom: 15px; border: 1px solid #e4e7ed;">
          <span style="flex: 1; word-break: break-all; font-family: monospace; color: #409eff; font-size: 14px; line-height: 1.5;" id="deploy-url-text">${deployUrl}</span>
          <button onclick="window.copyDeployUrl('${deployUrl}')" style="background: #409eff; color: white; border: none; padding: 6px 12px; border-radius: 4px; cursor: pointer; font-size: 12px; display: flex; align-items: center; gap: 4px; transition: background-color 0.3s; min-width: 60px; justify-content: center;" onmouseover="this.style.background='#337ecc'" onmouseout="this.style.background='#409eff'">
            📋 复制
          </button>
        </div>
        <p style="color: #909399; font-size: 14px;">是否立即跳转到部署的应用？</p>
      </div>
    `,
    showCancelButton: true,
    confirmButtonText: '立即跳转',
    cancelButtonText: '稍后访问',
    confirmButtonClass: 'el-button--primary',
    cancelButtonClass: 'el-button--default',
    beforeClose: (action, instance, done) => {
      if (action === 'confirm') {
        // 用户选择跳转
        window.open(deployUrl, '_blank')
      }
      done()
    }
  }).then(() => {
    // 用户点击确定跳转
    // 清理全局函数
    delete window.copyDeployUrl
  }).catch(() => {
    // 用户点击取消或关闭，不做任何操作
    // 清理全局函数
    delete window.copyDeployUrl
  })

  // 将复制函数暴露到全局，供HTML中的按钮调用
  window.copyDeployUrl = copyToClipboard
  
  // 将调试函数暴露到全局
  window.debugMessageContent = debugMessageContent
  window.testScriptSetupHandling = testScriptSetupHandling
}

// 复制到剪贴板
const copyToClipboard = async (text) => {
  try {
    await navigator.clipboard.writeText(text)
    proxy.$modal.msgSuccess('URL已复制到剪贴板')
  } catch (error) {
    // 降级方案：使用传统的复制方法
    const textArea = document.createElement('textarea')
    textArea.value = text
    document.body.appendChild(textArea)
    textArea.select()
    try {
      document.execCommand('copy')
      proxy.$modal.msgSuccess('URL已复制到剪贴板')
    } catch (fallbackError) {
      proxy.$modal.msgError('复制失败，请手动复制')
    }
    document.body.removeChild(textArea)
  }
}

// 格式化时间
const formatTime = (time) => {
  return parseTime(time, '{h}:{i}')
}

// 格式化日期时间
const formatDateTime = (dateTime) => {
  if (!dateTime) return '未知'
  return parseTime(dateTime, '{y}-{m}-{d} {h}:{i}:{s}')
}

// 处理代码高亮
const formatMessageWithHighlight = (content) => {
  if (!content) return ''
  
  // 检测代码块（三个反引号包围的内容）
  const codeBlockRegex = /```(\w+)?\n?([\s\S]*?)```/g
  
  let result = content.replace(codeBlockRegex, (match, language, code) => {
    // 如果指定了语言，使用指定语言进行高亮
    if (language && hljs.getLanguage(language)) {
      try {
        const highlighted = hljs.highlight(code.trim(), { language }).value
        return `<pre><code class="hljs language-${language}">${highlighted}</code></pre>`
      } catch (error) {
        // 代码高亮失败，使用原始代码
      }
    }
    
    // 自动检测语言
    try {
      const highlighted = hljs.highlightAuto(code.trim()).value
      return `<pre><code class="hljs">${highlighted}</code></pre>`
    } catch (error) {
      return `<pre><code>${code.trim()}</code></pre>`
    }
  })
  
  // 处理行内代码（单个反引号包围的内容）
  result = result.replace(/`([^`]+)`/g, '<code class="inline-code">$1</code>')
  
  // 特殊处理：转义HTML标签，防止被浏览器解析
  // 特别是处理 <script setup> 这样的标签
  result = result.replace(/</g, '&lt;').replace(/>/g, '&gt;')
  
  // 恢复代码块中的HTML标签（因为代码块已经被包装在<pre><code>中）
  result = result.replace(/&lt;pre&gt;&lt;code[^&]*?&gt;([\s\S]*?)&lt;\/code&gt;&lt;\/pre&gt;/g, (match, codeContent) => {
    return match.replace(/&lt;/g, '<').replace(/&gt;/g, '>')
  })
  
  // 恢复行内代码中的HTML标签
  result = result.replace(/&lt;code[^&]*?&gt;([\s\S]*?)&lt;\/code&gt;/g, (match, codeContent) => {
    return match.replace(/&lt;/g, '<').replace(/&gt;/g, '>')
  })
  
  // 不处理换行，让CSS的white-space属性来处理
  return result
}

// 滚动到底部
const scrollToBottom = () => {
  if (messagesContainer.value) {
    messagesContainer.value.scrollTop = messagesContainer.value.scrollHeight
  }
}

// 切换编辑模式
const toggleEditMode = () => {
  if (!visualEditor.value) {
    // 初始化可视化编辑器
    const iframe = document.querySelector('.preview-iframe')
    if (iframe) {
      visualEditor.value = new VisualEditor({
        onElementSelected: handleElementSelected,
        onElementHover: handleElementHover
      })
      visualEditor.value.init(iframe)
    }
  }
  
  if (visualEditor.value) {
    isEditMode.value = visualEditor.value.toggleEditMode()
  }
}

// 处理元素选中事件
const handleElementSelected = (elementInfo) => {
  // 检查是否已经选中了相同的元素（基于选择器）
  const existingIndex = selectedElements.value.findIndex(
    el => el.selector === elementInfo.selector && el.pagePath === elementInfo.pagePath
  )
  
  if (existingIndex === -1) {
    // 为元素添加唯一ID
    const elementWithId = {
      ...elementInfo,
      uniqueId: `${elementInfo.tagName}_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`
    }
    
    // 添加新选中的元素
    selectedElements.value.push(elementWithId)
    proxy.$modal.msgSuccess(`已选中元素: ${elementInfo.tagName}${elementInfo.id ? '#' + elementInfo.id : ''}`)
  } else {
    // 元素已存在，提示用户
    proxy.$modal.msgWarning('该元素已被选中')
  }
}

// 处理元素悬浮事件
const handleElementHover = (elementInfo) => {
  // 可以在这里添加悬浮时的处理逻辑
}

// 移除选中的元素
const removeSelectedElement = (uniqueId) => {
  // 使用唯一ID查找并删除元素
  const index = selectedElements.value.findIndex(el => el.uniqueId === uniqueId)
  if (index !== -1) {
    selectedElements.value.splice(index, 1)
  }
  
  // 如果所有元素都被移除且处于编辑模式，则退出编辑模式
  if (selectedElements.value.length === 0 && isEditMode.value) {
    toggleEditMode()
  }
}

// iframe 加载完成
const onIframeLoad = () => {
  // 预览页面加载完成，重新初始化可视化编辑器
  if (visualEditor.value) {
    visualEditor.value.onIframeLoad()
  }
  
  // 如果当前处于编辑模式，需要重新启用
  if (isEditMode.value && visualEditor.value) {
    // 延迟一点时间确保iframe完全加载
    setTimeout(() => {
      if (visualEditor.value) {
        visualEditor.value.enableEditMode()
      }
    }, 500)
  }
}

// 在新窗口打开
const openInNewTab = () => {
  if (previewUrl.value) {
    const newWindow = window.open(previewUrl.value, '_blank')
    
    // 尝试在新窗口加载后修改图标（如果同源的话）
    if (newWindow) {
      newWindow.addEventListener('load', () => {
        try {
          // 检查是否同源，如果是则可以修改
          const faviconLink = newWindow.document.querySelector('link[rel="icon"]')
          if (faviconLink) {
            faviconLink.href = '/favicon.svg'
            faviconLink.type = 'image/svg+xml'
          } else {
            // 如果没有图标链接，创建一个
            const link = newWindow.document.createElement('link')
            link.rel = 'icon'
            link.href = '/favicon.svg'
            link.type = 'image/svg+xml'
            newWindow.document.head.appendChild(link)
          }
        } catch (error) {
          // 跨域或其他错误，无法修改
          console.warn('无法修改新窗口图标:', error)
        }
      })
    }
  }
}

// 刷新预览
const refreshPreview = () => {
  if (previewUrl.value) {
    // 强制刷新iframe
    const iframe = document.querySelector('.preview-iframe')
    if (iframe) {
      iframe.src = iframe.src
    }
    
    // 重置可视化编辑器状态
    if (visualEditor.value) {
      visualEditor.value.disableEditMode()
      visualEditor.value = null
    }
    isEditMode.value = false
    selectedElements.value = []
  }
}

// 返回
const goBack = () => {
  router.push('/ai/home')
}


// 监听来自iframe的消息
const handleIframeMessage = (event) => {
  if (visualEditor.value) {
    visualEditor.value.handleIframeMessage(event)
  }
}

// 页面加载时获取应用信息
onMounted(() => {
  loadAppInfo()
  // 监听iframe消息
  window.addEventListener('message', handleIframeMessage)
})

// 调试函数：检查消息内容长度
const debugMessageContent = () => {
  console.log('=== 消息内容调试信息 ===')
  messages.value.forEach((message, index) => {
    if (message.role === 'assistant') {
      console.log(`消息 ${index}:`, {
        id: message.id,
        contentLength: message.content.length,
        contentPreview: message.content.substring(0, 100) + '...',
        contentEnd: message.content.substring(message.content.length - 100),
        thinkingLength: message.thinking ? message.thinking.length : 0,
        hasScriptTag: message.content.includes('<script'),
        scriptSetupPosition: message.content.indexOf('<script setup>')
      })
    }
  })
}

// 测试script setup处理
const testScriptSetupHandling = () => {
  
  // 添加测试消息
  const testMessage = {
    id: ++messageId,
    role: 'assistant',
    content: testContent,
    thinking: '',
    timestamp: new Date(),
    streaming: false
  }
  messages.value.push(testMessage)
}

// 页面卸载时清理资源
onUnmounted(() => {
  if (eventSource) {
    eventSource.close()
  }
  // 停止轮询
  stopPolling()
  // 移除消息监听器
  window.removeEventListener('message', handleIframeMessage)
  // 清理可视化编辑器
  if (visualEditor.value) {
    visualEditor.value.disableEditMode()
  }
})
</script>

<style scoped>
.ai-chat {
  height: 100vh;
  display: flex;
  flex-direction: column;
  background: #f5f7fa;
}

.chat-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 15px 20px;
  background: white;
  border-bottom: 1px solid #e1e8ed;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
}

.header-left {
  display: flex;
  align-items: center;
  gap: 15px;
}

.app-name {
  margin: 0;
  font-size: 1.3rem;
  color: #333;
  font-weight: 600;
}

.chat-content {
  flex: 1;
  display: flex;
  overflow: hidden;
}

.chat-panel {
  width: 50%;
  display: flex;
  flex-direction: column;
  background: white;
  border-right: 1px solid #e1e8ed;
}

.messages-container {
  flex: 1;
  overflow-y: auto;
  padding: 20px;
  scroll-behavior: smooth;
}

.message {
  display: flex;
  margin-bottom: 20px;
  gap: 12px;
}

.message.user {
  flex-direction: row-reverse;
}

.message-avatar {
  flex-shrink: 0;
}

.ai-avatar {
  width: 36px;
  height: 36px;
  border-radius: 50%;
  background: linear-gradient(45deg, #667eea, #764ba2);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 18px;
}

.tool-avatar {
  width: 36px;
  height: 36px;
  border-radius: 50%;
  background: linear-gradient(45deg, #f39c12, #e67e22);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 18px;
}

.message-content {
  max-width: 70%;
}

.message.user .message-content {
  text-align: right;
}

.message-bubble {
  background: #f8f9fa;
  padding: 12px 16px;
  border-radius: 18px;
  display: block;
  width: 100%;
  max-width: 100%;
  word-wrap: break-word;
  line-height: 1.5;
  white-space: pre-wrap;
  text-align: left;
  box-sizing: border-box;
}

.message.user .message-bubble {
  background: linear-gradient(45deg, #667eea, #764ba2);
  color: white;
}

.message.assistant .message-bubble {
  color: #2c3e50;
}

.message.tool_execution_result .message-bubble {
  color: #2c3e50;
  background: #f8f9fa;
  border: 1px solid #e1e8ed;
}

.message-time {
  font-size: 0.8rem;
  color: #999;
  margin-top: 5px;
}

.streaming-content {
  position: relative;
}

.typing-indicator {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  margin-left: 8px;
}

.typing-indicator span {
  width: 6px;
  height: 6px;
  background: #667eea;
  border-radius: 50%;
  animation: typing 1.4s infinite ease-in-out;
}

.typing-indicator span:nth-child(2) {
  animation-delay: 0.2s;
}

.typing-indicator span:nth-child(3) {
  animation-delay: 0.4s;
}

@keyframes typing {
  0%, 80%, 100% {
    transform: scale(0.8);
    opacity: 0.5;
  }
  40% {
    transform: scale(1);
    opacity: 1;
  }
}

/* AI消息容器样式 */
.ai-message-container {
  width: 100%;
}

/* 思考内容区域样式 */
.thinking-section {
  background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%);
  border: 1px solid #dee2e6;
  border-radius: 12px;
  margin-bottom: 12px;
  overflow: hidden;
}

.thinking-header {
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  color: white;
  padding: 8px 12px;
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 0.9rem;
  font-weight: 500;
  cursor: pointer;
  transition: background-color 0.2s ease;
  user-select: none;
}

.thinking-header:hover {
  background: linear-gradient(135deg, #5a6fd8 0%, #6a4190 100%);
}

.thinking-toggle {
  margin-left: auto;
  display: flex;
  align-items: center;
  transition: transform 0.3s ease;
}

.thinking-toggle i {
  font-size: 0.8rem;
}

.thinking-icon {
  font-size: 1rem;
}

.thinking-title {
  font-weight: 600;
}

.thinking-content {
  padding: 12px;
  font-size: 0.9rem;
  line-height: 1.6;
  color: #495057;
  background: white;
  white-space: pre-wrap;
  word-wrap: break-word;
  border-top: 1px solid #f1f3f4;
  max-height: 500px;
  overflow: hidden;
  transition: max-height 0.3s ease, padding 0.3s ease, opacity 0.3s ease;
  opacity: 1;
}

.thinking-content.thinking-collapsed {
  max-height: 0;
  padding: 0 12px;
  opacity: 0;
  border-top: none;
}

/* AI回复内容区域样式 */
.ai-response-section {
  position: relative;
}

.input-area {
  padding: 20px;
  border-top: 1px solid #e1e8ed;
  background: white;
}

.input-container {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.input-wrapper {
  position: relative;
  display: flex;
  align-items: flex-end;
}

.message-input {
  flex: 1;
  margin-right: 12px;
}

.message-input :deep(.el-textarea__inner) {
  border-radius: 12px;
  border: 1px solid #e1e8ed;
  resize: none;
  padding-right: 60px;
}

.send-button-wrapper {
  position: absolute;
  bottom: 2px;
  right: 14px;
  z-index: 10;
}

.send-btn {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  padding: 0;
  display: flex;
  align-items: center;
  justify-content: center;
}

.edit-btn {
  border-radius: 12px;
  padding: 12px 20px;
  margin-right: 10px;
  border: none !important;
  color: #1890ff !important;
  font-weight: 600 !important;
}

.edit-btn:focus {
  outline: none !important;
  box-shadow: none !important;
}

.edit-btn:hover {
  color: #40a9ff !important;
  background-color: #f0f8ff !important;
}

.edit-btn.is-success {
  color: #52c41a !important;
}

.edit-btn.is-success:hover {
  color: #73d13d !important;
  background-color: #f6ffed !important;
}

.input-tip {
  font-size: 0.8rem;
  color: #999;
  margin-top: 8px;
  text-align: center;
}

.preview-panel {
  width: 50%;
  display: flex;
  flex-direction: column;
  background: white;
}

.preview-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 15px 20px;
  border-bottom: 1px solid #e1e8ed;
  background: #fafbfc;
}

.preview-header h3 {
  margin: 0;
  font-size: 1.1rem;
  color: #333;
}

.preview-actions {
  display: flex;
  gap: 8px;
}

.preview-content {
  flex: 1;
  position: relative;
  overflow: hidden;
}

.preview-placeholder,
.preview-loading,
.preview-building {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  height: 100%;
  color: #999;
  text-align: center;
}

.preview-placeholder p,
.preview-loading p,
.preview-building p {
  margin-top: 20px;
  font-size: 1.1rem;
}

.build-status-text {
  font-size: 0.9rem !important;
  color: #666 !important;
  margin-top: 8px !important;
}

.preview-iframe {
  width: 100%;
  height: 100%;
  border: none;
  background: white;
}

@media (max-width: 768px) {
  .chat-content {
    flex-direction: column;
  }
  
  .chat-panel,
  .preview-panel {
    width: 100%;
  }
  
  .preview-panel {
    height: 40vh;
  }
  
  .chat-header {
    padding: 10px 15px;
  }
  
  .header-left {
    gap: 10px;
  }
  
  .app-name {
    font-size: 1.1rem;
  }
  
  .message-content {
    max-width: 85%;
  }
  
  .message-bubble pre {
    padding: 12px;
    font-size: 13px;
  }
}

/* 代码高亮样式 */
.message-bubble pre {
  background: #f6f8fa;
  border: 1px solid #e1e4e8;
  border-radius: 6px;
  padding: 16px;
  margin: 8px 0;
  overflow-x: auto;
  font-family: 'SF Mono', Consolas, 'Liberation Mono', Menlo, monospace;
  font-size: 14px;
  line-height: 1.45;
}

.message-bubble pre code {
  background: transparent;
  border: none;
  padding: 0;
  font-family: inherit;
}

.message-bubble .inline-code {
  background: #f3f4f6;
  border: 1px solid #e5e7eb;
  border-radius: 3px;
  padding: 2px 4px;
  font-family: 'SF Mono', Consolas, 'Liberation Mono', Menlo, monospace;
  font-size: 0.9em;
  color: #d73a49;
}

.message.user .message-bubble .inline-code {
  background: rgba(255, 255, 255, 0.2);
  border-color: rgba(255, 255, 255, 0.3);
  color: #fff;
}

/* 应用详细信息弹窗样式 */
.app-detail-content {
  padding: 20px;
}

.init-prompt {
  background: #f5f7fa;
  padding: 10px;
  border-radius: 6px;
  border-left: 4px solid #409eff;
  font-size: 14px;
  line-height: 1.5;
  white-space: pre-wrap;
  word-break: break-word;
  max-height: 150px;
  overflow-y: auto;
  color: #303133;
}

.detail-actions {
  text-align: center;
}

.loading-content {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  color: #999;
}

.loading-content .el-icon {
  font-size: 24px;
  margin-bottom: 10px;
}

/* 应用封面图片样式 */
.app-cover-image {
  width: 80px;
  height: 60px;
  object-fit: cover;
  border-radius: 6px;
  border: 1px solid #e1e8ed;
  cursor: pointer;
  transition: transform 0.3s ease;
}

.app-cover-image:hover {
  transform: scale(1.1);
}

/* 用户头像图片样式 */
.user-avatar-image {
  width: 40px;
  height: 40px;
  object-fit: cover;
  border-radius: 50%;
  border: 2px solid #e1e8ed;
}

/* 创建者信息区域样式 */
.creator-info {
  margin-top: 20px;
  padding-top: 20px;
  border-top: 1px solid #e1e8ed;
}

.creator-info h4 {
  margin: 0 0 15px 0;
  color: #2c3e50;
  font-size: 16px;
  font-weight: 600;
}

/* 描述列表优化 */
:deep(.el-descriptions__label) {
  font-weight: 600;
  color: #606266;
  width: 120px;
}

:deep(.el-descriptions__content) {
  color: #303133;
}

/* 优先级评分样式 */
:deep(.el-rate__text) {
  color: #ff9900;
  font-weight: 600;
}

/* 标签样式优化 */
:deep(.el-tag) {
  font-weight: 500;
}

/* 图片预览样式 */
.image-preview-container {
  display: flex;
  justify-content: center;
  align-items: center;
  width: 100%;
  height: 500px;
}

.preview-image {
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
  border-radius: 8px;
  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);
  cursor: pointer;
  transition: transform 0.3s ease;
}

.preview-image:hover {
  transform: scale(1.05);
}

/* 图片预览弹窗样式优化 */
:deep(.el-dialog) {
  background: rgba(255, 255, 255, 0.95);
  backdrop-filter: blur(10px);
}

:deep(.el-dialog__header) {
  padding: 20px 20px 10px 20px;
  border-bottom: 1px solid #e1e8ed;
}

:deep(.el-dialog__body) {
  padding: 20px;
}

/* 选中元素信息显示区域样式 */
.selected-elements-area {
  padding: 15px 20px;
  border-top: 1px solid #e1e8ed;
  background: #fafbfc;
  max-height: 200px;
  overflow-y: auto;
}

.element-alert {
  margin-bottom: 10px;
}

.element-alert:last-child {
  margin-bottom: 0;
}

.element-info {
  padding: 8px 0;
}

.element-basic {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 8px;
}

.tag-name {
  background: #409eff;
  color: white;
  padding: 2px 6px;
  border-radius: 3px;
  font-size: 12px;
  font-weight: 500;
}

.element-id {
  background: #67c23a;
  color: white;
  padding: 2px 6px;
  border-radius: 3px;
  font-size: 12px;
  font-weight: 500;
}

.element-class {
  background: #e6a23c;
  color: white;
  padding: 2px 6px;
  border-radius: 3px;
  font-size: 12px;
  font-weight: 500;
}

.element-text {
  color: #606266;
  font-size: 13px;
  line-height: 1.4;
  margin-bottom: 8px;
  background: #f5f7fa;
  padding: 6px 8px;
  border-radius: 4px;
  border-left: 3px solid #409eff;
}

.element-selector {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 12px;
}

.selector-label {
  color: #909399;
  font-weight: 500;
}

.selector-code {
  background: #f5f7fa;
  color: #e6a23c;
  padding: 2px 6px;
  border-radius: 3px;
  font-family: 'SF Mono', Consolas, 'Liberation Mono', Menlo, monospace;
  font-size: 11px;
  border: 1px solid #e1e8ed;
}

/* 编辑模式状态指示 */
.edit-mode-indicator {
  position: fixed;
  top: 50%;
  right: 20px;
  transform: translateY(-50%);
  background: #52c41a;
  color: white;
  padding: 10px 15px;
  border-radius: 20px;
  font-size: 14px;
  font-weight: 500;
  z-index: 1000;
  box-shadow: 0 4px 12px rgba(82, 196, 26, 0.3);
  animation: pulse 2s infinite;
}

@keyframes pulse {
  0% {
    transform: translateY(-50%) scale(1);
  }
  50% {
    transform: translateY(-50%) scale(1.05);
  }
  100% {
    transform: translateY(-50%) scale(1);
  }
}
</style>
